﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;

namespace Microsoft.Xna.Framework
{
    /// <summary>
    /// Contains the CurveKeys making up a Curve.
    /// </summary>
    [Serializable]
    public class CurveKeyCollection : ICollection<CurveKey>, IEnumerable<CurveKey>, IEnumerable
    {
        #region Private Fields
        private bool isReadOnly = false;
        private List<CurveKey> innerlist;
        #endregion

        #region Properties
        /// <summary>
        /// Gets the number of elements contained in the CurveKeyCollection.
        /// </summary>
        public int Count
        {
            get { return innerlist.Count; }
        }
        /// <summary>
        /// Returns a value indicating whether the CurveKeyCollection is read-only.
        /// </summary>
        public bool IsReadOnly
        {
            get { return this.isReadOnly; }
        }
        /// <summary>
        /// Gets or sets the element at the specified index.
        /// </summary>
        /// <param name="index">The array index of the element.</param>
        public CurveKey this[int index]
        {
            get { return innerlist[index]; }
            set
            {
                if (value == null)
                    throw new ArgumentNullException();

                if (index >= innerlist.Count)
                    throw new IndexOutOfRangeException();

                if (innerlist[index].Position == value.Position)
                    innerlist[index] = value;
                else
                {
                    innerlist.RemoveAt(index);
                    innerlist.Add(value);
                }
            }
        }
        #endregion

        #region Constructor
        /// <summary>
        /// Initializes a new instance of CurveKeyCollection.
        /// </summary>
        public CurveKeyCollection()
        {
            innerlist = new List<CurveKey>();
        }
        #endregion

        #region Private Methods
        IEnumerator IEnumerable.GetEnumerator()
        {
            return innerlist.GetEnumerator();
        }
        #endregion

        #region Public Methods
        /// <summary>
        /// Adds a CurveKey to the CurveKeyCollection.
        /// </summary>
        /// <param name="item">The CurveKey to add.</param>
        public void Add(CurveKey item)
        {
            if (item == null)
                throw new ArgumentNullException();

            if (innerlist.Count == 0)
            {
                this.innerlist.Add(item);
                return;
            }

            for (int i = 0; i < this.innerlist.Count; i++)
            {
                if (item.Position < this.innerlist[i].Position)
                {
                    this.innerlist.Insert(i, item);
                    return;
                }
            }

            this.innerlist.Add(item);
        }
        /// <summary>
        /// Removes all CurveKeys from the CurveKeyCollection.
        /// </summary>
        public void Clear()
        {
            innerlist.Clear();
        }
        /// <summary>
        /// Creates a copy of the CurveKeyCollection.
        /// </summary>
        public CurveKeyCollection Clone()
        {
            CurveKeyCollection ckc = new CurveKeyCollection();
            foreach (CurveKey key in this.innerlist)
                ckc.Add(key);
            return ckc;
        }
        /// <summary>
        /// Determines whether the CurveKeyCollection contains a specific CurveKey.
        /// </summary>
        /// <param name="item">true if the CurveKey is found in the CurveKeyCollection; false otherwise.</param>
        public bool Contains(CurveKey item)
        {
            return innerlist.Contains(item);
        }
        /// <summary>
        /// Copies the CurveKeys of the CurveKeyCollection to an array, starting at the array index provided.
        /// </summary>
        /// <param name="array">The destination of the CurveKeys copied from CurveKeyCollection. The array must have zero-based indexing.</param>
        /// <param name="arrayIndex">The zero-based index in the array to start copying from.</param>
        public void CopyTo(CurveKey[] array, int arrayIndex)
        {
            innerlist.CopyTo(array, arrayIndex);
        }
        /// <summary>
        /// Returns an enumerator that iterates through the CurveKeyCollection.
        /// </summary>
        public IEnumerator<CurveKey> GetEnumerator()
        {
            return innerlist.GetEnumerator();
        }
        /// <summary>
        /// Determines the index of a CurveKey in the CurveKeyCollection.
        /// </summary>
        /// <param name="item">CurveKey to locate in the CurveKeyCollection.</param>
        public int IndexOf(CurveKey item)
        {
            return innerlist.IndexOf(item);
        }
        /// <summary>
        /// Removes the first occurrence of a specific CurveKey from the CurveKeyCollection.
        /// </summary>
        /// <param name="item">The CurveKey to remove from the CurveKeyCollection.</param>
        public bool Remove(CurveKey item)
        {
            return innerlist.Remove(item);
        }
        /// <summary>
        /// Removes the CurveKey at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index of the item to remove.</param>
        public void RemoveAt(int index)
        {
            innerlist.RemoveAt(index);
        }
        #endregion
    }
}
